using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using Microsoft.Practices.CompositeWeb.Utility;

namespace WCSFContrib.Extensions.CompositeWeb.Configuration
{
    /// <summary>
	/// A collection of <see cref="ServiceElement"/>.
	/// </summary>
    public class ServiceConfigurationElementCollection : ConfigurationElementCollection
    {
		/// <summary>
		/// Initializes a new instance of <see cref="ServiceElementCollection"/>.
		/// </summary>
        public ServiceConfigurationElementCollection()
        {
        }

		/// <summary>
		/// Initializes a new <see cref="ServiceElementCollection"/>.
		/// </summary>
		/// <param name="services">The initial set of <see cref="ServiceElement"/>.</param>
		public ServiceConfigurationElementCollection(ServiceConfigurationElement[] services)
		{
			Guard.ArgumentNotNull(services, "services");

			foreach (ServiceConfigurationElement service in services)
			{
				BaseAdd(service);
			}
		}


		/// <summary>
		/// Indicates that an exception should be raised if a duplicate element is found.
		/// </summary>
        protected override bool ThrowOnDuplicate
        {
            get { return true; }
        }

		/// <summary>
		/// Adds a <see cref="ServiceElement"/> to the collection.
		/// </summary>
		/// <param name="service">A <see cref="ServiceElement"/> instance.</param>
        public void Add(ServiceConfigurationElement service)
        {
            BaseAdd(service);
        }

        /// <summary>
        /// Tests if the collection contains the configuration for the specified module name.
        /// </summary>
        /// <param name="moduleName">The name of the module to search the configuration for.</param>
        /// <returns><see langword="true"/> if a configuration for the module is present; otherwise <see langword="false"/>.</returns>
        public bool Contains(Type type)
        {
            return base.BaseGet(type) != null;
        }

		/// <summary>
		/// Searches the collection for all the <see cref="ServiceElement"/> that match the specified predicate.
		/// </summary>
		/// <param name="match">A <see cref="Predicate{T}"/> that implements the match test.</param>
		/// <returns>A <see cref="List{ServiceElement}"/> with the successful matches.</returns>
        public List<ServiceConfigurationElement> FindAll(Predicate<ServiceConfigurationElement> match)
        {
            List<ServiceConfigurationElement> found = new List<ServiceConfigurationElement>();
            foreach (ServiceConfigurationElement serviceElement in this)
            {
                if (match(serviceElement))
                {
                    found.Add(serviceElement);
                }
            }
            return found;
        }

		/// <summary>
		/// Gets the type of <see cref="ConfigurationElementCollectionType"/>.
		/// </summary>
        public override ConfigurationElementCollectionType CollectionType
        {
            get { return ConfigurationElementCollectionType.BasicMap; }
        }

		/// <summary>
		/// Gets the name to identify this collection in the configuration.
		/// </summary>
        protected override string ElementName
        {
            get { return "service"; }
        }

		/// <summary>
		/// Creates a new <see cref="ServiceElement"/>.
		/// </summary>
		/// <returns>A <see cref="ServiceElement"/>.</returns>
        protected override ConfigurationElement CreateNewElement()
        {
            return new ServiceConfigurationElement();
        }

		/// <summary>
		/// Gets the element key for specified element.
		/// </summary>
		/// <param name="element">The <see cref="ConfigurationElement"/> to get the key for.</param>
		/// <returns>An <see langword="object"/>.</returns>
		protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ServiceConfigurationElement)element).RegisterAs.GetHashCode().ToString() + ((ServiceConfigurationElement)element).Type.GetHashCode().ToString() ;
        }

		/// <summary>
		/// Gets the <see cref="ServiceElement"/> located at the specified index in the collection.
		/// </summary>
		/// <param name="index">The index of the element in the collection.</param>
		/// <returns>A <see cref="ModuleConfigurationElement"/>.</returns>
		public ServiceConfigurationElement this[int index]
        {
            get { return (ServiceConfigurationElement)base.BaseGet(index); }
        }
    }
}
